输入输出重定向

输入重定向是指把文件导入到命令中,而输出重定向则是指把原本要输出到屏幕的数据信息写入到指定文件中

  • 标准输入重定向(STDIN,文件描述符为 0):默认从键盘输入,也可从其他文件或命令中输入。
  • 标准输出重定向(STDOUT,文件描述符为 1):默认输出到屏幕。
  • 错误输出重定向(STDERR,文件描述符为 2):默认输出到屏幕。

输入重定向中用到的符号及其作用 :

符号 作用
命令 < 文件 将文件作为命令的标准输入
命令 << 分界符 从标准输入中读入,直到遇见分界符才停止
命令 < 文件 1 > 文件 2 将文件 1 作为命令的标准输入并将标准输出到文件 2

输出重定向中用到的符号及其作用

符号 作用
命令 > 文件 将标准输出重定向到一个文件中(清空原有文件的数据)
命令 2> 文件 将错误输出重定向到一个文件中(清空原有文件的数据)
命令 >> 文件 将标准输出重定向到一个文件中(追加到原有内容的后面)
命令 2>> 文件 将错误输出重定向到一个文件中(追加到原有内容的后面)
命令 >> 文件 2>&1 或 命令 &>> 文件 将标准输出与错误输出共同写入到文件中(追加到原有内容的后面)

例:

1
[kanxz@study ~]$ man bash > readme.txt

如果没有readme.txt,会自动创建,其内容为bash的帮助文档

1
2
3
4
5
[kanxz@study ~]$ echo "Text_1" > readme.txt
[kanxz@study ~]$ echo "Text_2" >> readme.txt
[kanxz@study ~]$ cat readme.txt
Text_1
Text_2

虽然都是输出重定向技术,但是不同命令的标准输出和错误输出还是有区别的:

test.txt 这个文件是真实存在的,因此使用标准输出即可将原本要输出到屏幕的信息写入到文件中,而错误的输出重定向则依然把信息输出到了屏幕上。

1
2
3
4
5
6
7
8
9
[kanxz@study ~]$ ls -l test.txt
-rw-rw-r--. 1 kanxz kanxz 0 Feb 24 17:38 test.txt
[kanxz@study ~]$ ls -l test.txt > readme.txt
[kanxz@study ~]$ cat readme.txt
-rw-rw-r--. 1 kanxz kanxz 0 Feb 24 17:38 test.txt
[kanxz@study ~]$ ls -l test.txt 2> readme.txt
-rw-rw-r--. 1 kanxz kanxz 0 Feb 24 17:38 test.txt
[kanxz@study ~]$ cat readme.txt
[kanxz@study ~]$

而xxx这个文件不存在:

1
2
3
4
5
6
7
[kanxz@study ~]$ ls -l xxx
ls: cannot access xxx: No such file or directory
[kanxz@study ~]$ ls -l xxx > readme.txt
ls: cannot access xxx: No such file or directory
[kanxz@study ~]$ ls -l xxx 2> readme.txt
[kanxz@study ~]$ cat readme.txt
ls: cannot access xxx: No such file or directory

管道命令符

同时按下键盘上的 Shift+\ 键即可输入管道符,其执行格式为“命令 A | 命令 B”。命令符的作用也可以用一句话来概括“把前一个命令原本要输出到屏幕的数据当作是后一个命令的标准输入”

统计所有被限制登录系统的用户数:

  • 找出被限制登录用户的命令是 grep nologin /etc/passwd
  • 统计文本行数的命令则是 wc -l
1
2
[kanxz@study ~]$ grep nologin /etc/passwd | wc -l
38

用翻页的形式查看/etc 目录中的文件列表及属性信息(这些内容默认会一股脑儿地显示到屏幕上,根本看不清楚):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[kanxz@study ~]$ ls -l /etc/ | more
total 1356
-rw-r--r--. 1 root root 5090 Aug 6 2019 DIR_COLORS
-rw-r--r--. 1 root root 5725 Aug 6 2019 DIR_COLORS.256color
-rw-r--r--. 1 root root 4669 Aug 6 2019 DIR_COLORS.lightbgcolor
-rw-r--r--. 1 root root 94 Mar 25 2017 GREP_COLORS
-rw-r--r--. 1 root root 1704 Aug 13 2019 GeoIP.conf
drwxr-xr-x. 8 root root 145 Feb 22 22:53 NetworkManager
drwxr-xr-x. 2 root root 92 Feb 22 22:53 PackageKit
drwxr-xr-x. 2 root root 25 Feb 22 22:52 UPower
drwxr-xr-x. 6 root root 103 Feb 22 22:51 X11
drwxr-xr-x. 3 root root 101 Feb 22 22:52 abrt
-rw-r--r--. 1 root root 16 Feb 22 22:58 adjtime
-rw-r--r--. 1 root root 1518 Jun 7 2013 aliases
-rw-r--r--. 1 root root 12288 Feb 22 23:01 aliases.db
drwxr-xr-x. 3 root root 65 Feb 22 22:53 alsa
drwxr-xr-x. 2 root root 4096 Feb 22 22:57 alternatives
-rw-------. 1 root root 541 Aug 9 2019 anacrontab
-rw-r--r--. 1 root root 55 Aug 8 2019 asound.conf
-rw-r--r--. 1 root root 1 Oct 31 2018 at.deny
drwxr-x---. 3 root root 43 Feb 22 22:52 audisp
drwxr-x---. 3 root root 83 Feb 22 23:01 audit
drwxr-xr-x. 4 root root 71 Feb 22 22:53 avahi
drwxr-xr-x. 2 root root 4096 Feb 22 22:53 bash_completion.d
--More--

命令行的通配符

通配符就是通用的匹配信息的符号,比如星号(*)代表匹配零个或多个字符,问号(?)代表匹配单个字符,中括号内加上数字[0-9]代表匹配 0~9之间的单个数字的字符,而中括号内加上字母[abc]则是代表匹配 a、b、c 三个字符中的任意一个字符。

1
2
3
4
5
[kanxz@study ~]$ ls -l /dev/sda*
brw-rw----. 1 root disk 8, 0 Feb 24 19:05 /dev/sda
brw-rw----. 1 root disk 8, 1 Feb 24 19:05 /dev/sda1
brw-rw----. 1 root disk 8, 2 Feb 24 19:05 /dev/sda2
brw-rw----. 1 root disk 8, 3 Feb 24 19:05 /dev/sda3

常用的转义字符

4 个最常用的转义字符如下所示:

  • 反斜杠(\):使反斜杠后面的一个变量变为单纯的字符串。
  • 单引号( ‘’):转义其中所有的变量为单纯的字符串。
  • 双引号(""):保留其中的变量属性,不进行转义处理。
  • 反引号(``):把其中的命令执行后返回结果。

我们先定义一个名为 PRICE 的变量并赋值为 5,然后输出以双引号括起来的字符串与变量信息:

1
2
3
[kanxz@study ~]$ PRICE=5
[kanxz@study ~]$ echo "Price is $PRICE"
Price is 5

接下来,我们希望能够输出“Price is $5”,即价格是 5 美元的字符串内容,但碰巧美元符号与变量提取符号合并后的$$作用是显示当前程序的进程 ID 号码,于是命令执行后输出的内容并不是我们所预期的:

1
2
[kanxz@study ~]$ echo "Price is $$PRICE"
Price is 2649PRICE

要想让第一个“$”乖乖地作为美元符号,那么就需要使用反斜杠(\)来进行转义,将这个命令提取符转义成单纯的文本,去除其特殊功能。

1
2
[kanxz@study ~]$ echo "Price is \$$PRICE"
Price is $5

而如果只需要某个命令的输出值时,可以像`命令`这样,将命令用反引号括起来,达到预期的效果。例如,将反引号与 uname -a 命令结合,然后使用 echo 命令来查看本机的 Linux版本和内核信息:

1
2
[kanxz@study ~]$ echo `uname -a`
Linux study.centos.kanxz 3.10.0-1062.el7.x86_64 #1 SMP Wed Aug 7 18:08:02 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

重要的环境变量

命令在 Linux 中的执行分为 4 个步骤:

  • 判断用户是否以绝对路径或相对路径的方式输入命令(如/bin/ls),如果是的话则直接执行

  • Linux 系统检查用户输入的命令是否为“别名命令”,即用一个自定义的命令名称来替换原本的命令名称。可以用 alias 命令来创建一个属于自己的命令别名,格式为“alias 别名=命令”。若要取消一个命令别名,则是用 unalias 命令,格式为“unalias 别名”。

  • Bash 解释器判断用户输入的是内部命令还是外部命令。内部命令是解释器内部的指令,会被直接执行;而用户在绝大部分时间输入的是外部命令,这些命令交由步骤 4 继续处理。可以使用“type 命令名称”来判断用户输入的命令是内部命令还是外部命令。

  • 系统在多个路径中查找用户输入的命令文件,而定义这些路径的变量叫作 PATH,PATH 是由多个路径值组成的变量,每个路径值之间用冒号间隔,对这些路径的增加和删除操作将影响到 Bash 解释器对Linux 命令的查找。

    1
    2
    [kanxz@study ~]$ echo $PATH
    /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/kanxz/.local/bin:/home/kanxz/bin